package common

import (
	"encoding/base64"
	"errors"
	"fmt"
	"os"
	"reflect"
	"time"
)

func GroupByField(data interface{}, fieldName string) map[interface{}][]interface{} {
	grouped := make(map[interface{}][]interface{})

	// 使用反射获取切片类型的值
	sliceValue := reflect.ValueOf(data)
	if sliceValue.Kind() != reflect.Slice {
		panic("Input data must be a slice")
	}

	// 遍历切片中的元素并进行分组
	for i := 0; i < sliceValue.Len(); i++ {
		element := sliceValue.Index(i).Interface()
		fieldValue := reflect.ValueOf(element).FieldByName(fieldName).Interface()
		grouped[fieldValue] = append(grouped[fieldValue], element)
	}

	return grouped
}

type LogLevel int

const (
	Debug LogLevel = iota
	Info
	Warning
	Error
)

// LogToFile 将消息写入日志文件
func WriteLog(level LogLevel, message string, data interface{}) error {
	// 获取当前日期和时间
	currentTime := time.Now()
	year, month, day := currentTime.Date()

	// 构建日志文件夹路径
	logDir := fmt.Sprintf("log/%d/%02d", year, month)

	// 确保日志文件夹存在
	if err := os.MkdirAll(logDir, os.ModePerm); err != nil {
		return err
	}

	// 构建日志文件名，包括当前日期
	logFileName := fmt.Sprintf("%s/%02d.log", logDir, day)

	// 打开或创建日志文件
	logFile, err := os.OpenFile(logFileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		return err
	}
	defer func() {
		if closeErr := logFile.Close(); closeErr != nil {
			fmt.Printf("Error closing log file: %v\n", closeErr)
		}
	}()

	// 将消息写入日志
	currentTimeStr := currentTime.Format("2006-01-02 15:04:05")
	logMessage := fmt.Sprintf("[%s] [%s] %s\n", levelString(level), currentTimeStr, message)
	_, err = logFile.WriteString(logMessage)
	if err != nil {
		return err
	}

	// 将数据写入日志
	logFile.WriteString("Data:\n")

	// 使用反射检查数据类型并写入日志
	dataType := reflect.TypeOf(data)
	dataValue := reflect.ValueOf(data)

	switch dataType.Kind() {
	case reflect.Slice, reflect.Array:
		for i := 0; i < dataValue.Len(); i++ {
			item := dataValue.Index(i)
			logFile.WriteString(fmt.Sprintf("- %v\n", item.Interface()))
		}
	default:
		logFile.WriteString(fmt.Sprintf("- %v\n", data))
	}

	return nil
}

// levelString 返回日志级别的字符串表示
func levelString(level LogLevel) string {
	switch level {
	case Debug:
		return "DEBUG"
	case Info:
		return "INFO"
	case Warning:
		return "WARNING"
	case Error:
		return "ERROR"
	default:
		return "UNKNOWN"
	}
}

// 轻量 XOR 密钥，保持和前端一致
var xorKey = "0123456789abcdef"

// XOR 加密/解密（对称）
func xorCipher(data string, key string) string {
	result := make([]byte, len(data))
	keyLen := len(key)
	for i := 0; i < len(data); i++ {
		result[i] = data[i] ^ key[i%keyLen]
	}
	return string(result)
}

// Encrypt 轻量加密
func Encrypt(plaintext string) (string, error) {
	if plaintext == "" {
		return "", errors.New("空数据")
	}
	xored := xorCipher(plaintext, xorKey)
	return base64.StdEncoding.EncodeToString([]byte(xored)), nil
}

// Decrypt 轻量解密
func Decrypt(ciphertext string) (string, error) {
	if ciphertext == "" {
		return "", errors.New("空数据")
	}
	decoded, err := base64.StdEncoding.DecodeString(ciphertext)
	if err != nil {
		return "", err
	}
	decrypted := xorCipher(string(decoded), xorKey)
	return decrypted, nil
}
